4.1 React.js with Node.js

  1. Motivations
    • React is an open-source web UI framework (library) created by Facebook in 2013. It quickly became one of the most popular frontend frameworks for UI development. It is adored by web developers because it requires minimal effort in coding and its ability to provide an outstanding user experience, making it one of the best UI frameworks of all time.
    • Programming languages used: JavaScript/JSX (HTML+JavaScript syntax)
    • An example from https://reactjs.org/docs/add-react-to-a-website.html

  2. Introduction to React
    • When should you use React (Reference: https://www.communicationcrafts.com/frontend-frameworks-for-web-development-in-2021/)
      • Single page or cross-platform application development
      • Data visualization tools
      • Social networks
      • Web apps
      • Messaging apps
      • Blogs (Personal or professional)
    • PROS of React (Reference: https://www.communicationcrafts.com/frontend-frameworks-for-web-development-in-2021/)
      • Easy to learn and use: Developers familiar with JavaScript can learn to use React in a matter of days. 69.7% of developers prefer JavaScript based frameworks over other programming languages.
      • Virtual Document Object Model (DOM): The tree-like structure of an HTML program is known as DOM. The users' actions on a website trigger an update that rewrites the entire DOM, requiring more resources. A virtual DOM works more efficiently because it changes only the elements that need manipulation.
      • Requires less coding: Easy to create highly functional web UIs
      • Reusability: React has reusable HTML codes that make a developer's life quite easy. It is easier to make and maintain web UIs because of this feature.
      • Downward data flow: React framework's data flow is relatively simple. It has a straightforward downward data flow that is easy to track and work with.
    • CONS of React (Reference: https://www.communicationcrafts.com/frontend-frameworks-for-web-development-in-2021/)
      • Continuous updates: Developers have to constantly re-learn new ways of coding because web UI the framework changes at a very rapid pace.
      • Poor documentation: The extension libraries are not efficiently updated by the supporting community.
      • JSX complications: React uses syntax that is a combination of HTML and JavaScript. It has a steep learning curve and is difficult for amateur developers to work with.

  3. Examples
    • An example from https://reactjs.org/docs/add-react-to-a-website.html
      <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
      <div id="like_button_container">
      </div>
      <!-- Load our React component. -->
      <script src="like_button.js"></script>
      
      <!-- like_button.js
      'use strict';
      
      const e = React.createElement;
      
      class LikeButton extends React.Component {
        constructor(props) {  // props: object for attribute properties
          super(props);
          this.state = { liked: false };
        }
      
        render() {
          if (this.state.liked) {
            return 'You liked this.';
          }
      
          // JS
          return e(
            'button',
            { onClick: () => this.setState({ liked: true }) },
            'Like'
          );
          /* or
          // JSX
          //   What do you think is returned?
          return (
            <button onClick={() => this.setState({ liked: true })}>
              Like
            </button>  // Is it a string value? What is it?
          );
          */
        }
      }
      
      const domContainer = document.querySelector('#like_button_container');
      ReactDOM.render(e(LikeButton), domContainer);  // It is the main idea.
      -->
      
    • Try the above example!
    • Optionally Babel for JSX can be used.
      What is Babel?
      https://reactjs.org/docs/add-react-to-a-website.html#optional-try-react-with-jsx
      <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
      <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
      <div id="like_button_container_jsx"></div>
      <!-- Load our React component. -->
      <script type="text/babel" src="like_button_jsx.js"><!-- See the above code for this example. -->
      
    • Hello World! from https://reactjs.org/docs/hello-world.html
      <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
      <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
      <div id='hello-world-container'></div>
      <script type="text/babel">
          ReactDOM.render(
            <h1>Hello, world!</h1>,  // ?
            document.getElementById('hello-world-container')
          );
      </script>
      
    • Try the "Memo" example! It was developed with React and Node. You will develop this app later.

  4. React Introduction from https://www.w3schools.com/react/react_intro.asp]

  5. React Tutorial, and some other topics from w3schools.com
    • React Get Started
      • React directly in HTML with Babel, or
      • Setting up a React development environment so that JSX can be executed at the server side for app development
        Note that you can install Node on your local [e.g., Ubuntu] computer and set up a React development environment.
        • For this class, on cs.tru.ca,
        • Install vite build tool if not installed
          $ npm install -g create-vite
        • Create a react app named "my-react-app"
          $ npm create vite@latest my-react-app -- --template react
          Enter -> Enter -> h + Enter -> q + Enter
        • $ cd my-react-app
        • Install dependencies
          $ npm install
        • Insert 'server' in vite.config.js.
          // in defineConfig,
            server: {
              port: 5173,  // your portnumber for this class
              host: "0.0.0.0",  // listen to all IP addresses
            },
          
        • Run the React app.
          $ npm run dev
          'dev' means development phase. The above step will run a web server with the above port number, so that your app can be accessed from a web browser.
        • You can access http://198.162.21.132:yourportnumber on your web browser. Try it! (Note that you sould not use cs.tru.ca. Something more needs to be added to support domain names in this development phase.)
          How to stop the React app on cs.tru.ca? ^C.
        • Trial 0. Connect to cs.tru.ca with your account, and try to complete the steps in the above.
        • How to develop an React app? We need to modify the React application: src/App.jsx
        • Later, $ npm run build. ('build' means building the code for depolyment.) See the last subsection.
      • Tutorial schedule from here:
        • A bit of prerequisites
        • React with Babel on web browser because the computers in lab do not have Node.js. We need to use cs.tru.ca.
        • How to move and convert the React code with Babel to the server-side React dev environment
        • How to deploy a React app

    • React uses ES6. Let's learn Template Literals, ES6 Classes, Array method - .map(), Destructuring, and Modules.
      • Here it an example of .map(), arrow function, and template literal.
        const data = ['apple', 'banana', 'orange'];
        const list = data.map((item) => `<li>${item}</li>`);
        //const list = data.map(function(item) { return `<li>${item}</li>`; });
        alert(list);
        
      • Try this for React and .map()!
      • Trial 1. Let's try the above code.

    • [React Render HTML:] React renders HTML to the web page.
      • Can you explain what the basic idea of React is?
      • Questions:
        • Q1. How to make a group of HTML elements?
        • Q2. Templating?
        • Q3. How to support events?
        • Q4. How to support 'state', i.e., internal data, so that multiple subgroups (called components) can be bound to the data?

    • React JSX: JSX allows us to write HTML elements in JavaScript.
      • A group of HTML elements that include JavaScript templating with '{ ... }', not '${...}'.
      • A tree like structure of HTML elements and components
      • Closing tags are always required. E.g., <input ... /> or <> ... </>
      • 'className' is used instead of the 'class' attribute in a start tag.
      • 'onEventname' is used instead of the 'oneventname' attribute in a start tag. E.g., onClick
      • For example,
        const myelement = <h1>I Love JSX {5 + 5} times!</h1>;  // It is an example of JSX. One top level HTML element.
        const myAnoterhExample = (
            <>
                <hr />
                <h1 className='test'>I Love JSX {5 + 5} times!</h1>
            </>
        )
        ReactDOM.render(myelement, document.getElementById('root'));
        

    • React Components
      • A component is like a function that includes functional logic and state variables, and returns a group of HTML elements that can be rendered in ReactDOM. In a component, state variables can be bound to the group of HTML elements.
      • Two types: class components, and function components
        <ComponentName [attr=value ...] />
        
      • Components can be nested.
      • Let's study the next Trial closely.
      • Trial 2.1 Let's try use a function component that returns the next HTML element
        <h2>What a great day!</h2>
        
      • Trial 2.2 Let's try use two function components. One component is used in another one. The two components also use a parameter for the object of attributes.
      • In the above two Trials, what questions that we raised before are answered?
        • Q1
        • Q2
          • { ... } within JSX code in a component
          • How can data be passed to a component?
            ReactDOM.render(<Weather islike='nice' />, document.getElementById('tr2-root3'));
            let data=...; ReactDOM.render(<Weather attrname={data} />, document.getElementById('tr2-root3'));
          • An object or an array can be passed as an attribute (or called property). E.g., data={ {name:"John", age:23} }
          • props are read-only.
      • Trial 3. Let's try to use a class component.
      • How to resolve Q3 and Q4?

    • React Props

    • React Events
      • Trial 4.1 Let's try to include event handling code into a component.
      • Trial 4.2 Let's try to include event handling code into a component.
      • Trial 4.3 Let's try to include event handling code into a component.

      • Trial 5. Let's try to include 'a variable in closure' into a component. Is the input value printed in <p>? What do you have to do? Data-view binding?
      • How to resolve Q4?

    • React Hooks and React useState Hooks
      • Hooks allow function components to have access to state, and because of this, class components are generally no longer needed.
      • Requirements: Only inside React function components; At the top level of a component; Not be conditional
      • Trial 6. Let's try to include a stateHook into a component.
      • Note that only when state data is changed, related components will be re-rendered. What if state data is an array or object and an element or a property is changed? The answer is no, because the state data has a reference value and the reference value would not be changed. For example,
        {data, setData} = useState([0, 1, 2, 3]);
        ...
        data[2] = 22;
        setData(data);  // It won't work.
        
        //---------------------------------------------
        data[2] = 22;
        let tmpData = [];
        for (let i = 0; i < data.length; i++) 
            tmpData[i] = data[i];
        setData(tmpData);  // It will work.
        data = tmpData;
        

    • There are more topics in your capable hands.

    • Let's use Node.js to compile JSX code, so that Babel is not used. Here is a simple example.
      • Did you finish Trial 0? Please complete it!
      • ES modules are supprted.
      • Directories and files in my-react-app: [for Trial 7]
        • ./
          • index.html - a template that includes
            <div id='root'>
            <script type="module" src="/src/main.jsx"></script>
            
          • ...
        • ./src/
          • main.jsx - JavaScript code to support JSX code
            import { StrictMode } from "react";  // NOT inclusion of libraries such as https://unpkg.com/react@17/umd/react.development.js
            import { createRoot } from "react-dom/client";
            import "./index.css";  // Check this out!
            import App from "./App.jsx";
            
            createRoot(document.getElementById('root')).render(  // NOT ReactDOM.render
                <StrictMode>
                    <App />
                </StrictMode>,
            )
            
          • index.css
          • body {
                margin:5px;
            }
            
          • App.jsx
            import "./App.css";
            import { useState } from "react";
            
            const App = () {  // From Trial 6
                const [data, setDataaa] = ???("Message here!");
                const readTR6 = (message) => {    // To be called from the event listener on the next button
                    alert(message);
                    // data = message;  // Not this way!!!
                    ???(message);  // Will data be bound to the <p> in the below?
                                         // How?
                }
                return (
                    <>
                        <input id="tr6-input" />
                        <button onClick={ () => {
                                readTR6(document.getElementById("tr6-input").value);
                            }
                        }>Read!</button>
                        <p>{ ??? }</p>  {/* state; maybe another component */}
                    </>
                )
            }
            
            export ????;
            
          • App.css
            p {
                font-size:40px;
                background-color:Cyan;
            }
            
          • ...
      • Trial 7. After update the above files, in my-react-app, execute $ npm run dev
        How to test? (Note that you need to use your port number in vite.config.js.)

  6. How to build and deploy - an example
    • When you complete the development, in the "my-react-app" directory,
      • Add the following in defineConfig in "vite.config.js".
        ... defineConfig {
            ...
            base:"./",  // default is "/"
            ...
        }
        
      • $ npm run build
      • If ~/public_html/react-app were not created, you need to create the directory. Or different directory, e.g., Week5.
      • $ cp -r dist/* ~/public_html/react-app
      • $ find ~/public_html/react-app -type d -exec chmod 711 {} \;
      • $ find ~/public_html/react-app -type f -exec chmod 644 {} \;
    • Trial 8. Complete the above steps, and test the app with "https://cs.tru.ca/~youraccountname/react-app".

  7. Learning outcomes